package com.nut.lmsc.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.nut.lmsc.api.req.CancelOrderReq;
import com.nut.lmsc.api.req.OrderQueryReq;
import com.nut.lmsc.api.req.OrderReq;
import com.nut.lmsc.api.resp.SubmitOrderResp;
import com.nut.lmsc.common.FailMessage;
import com.nut.lmsc.common.Result;
import com.nut.lmsc.entity.*;
import com.nut.lmsc.enums.IdTagEnum;
import com.nut.lmsc.enums.OrderStatusEnum;
import com.nut.lmsc.interceptor.MerchantJwt;
import com.nut.lmsc.mapper.*;
import com.nut.lmsc.service.OrderService;
import com.nut.lmsc.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.Set;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderGoodsMapper orderGoodsMapper;

    @Autowired
    private OrderActionLogMapper orderActionLogMapper;

    @Autowired
    private GoodsMapper goodsMapper;

    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private MemberCouponMapper memberCouponMapper;

    @Override
    public Result<IPage<Order>> listPage(OrderQueryReq req) {
        IPage<Order> list = orderMapper.listPage(req.newPage(),
                req.getMemberId(), req.getOrderId(), req.getShopId(), req.getName(),
                req.getMobile(), req.getStatus(), req.getStartTime(), req.getEndTime(), req.getCode());
        return Result.ok(list);
    }

    @Override
    public Result updateById(Order order) {
        order.setStatus(null);
        order.setMemberId(null);
        order.setName(null);
        order.setMobile(null);
        orderMapper.updateById(order);
        return Result.ok();
    }

    @Override
    public Result deleteByIds(Set<Integer> ids) {
        for (Integer id : ids) {
            orderMapper.deleteById(id);
        }
        return Result.ok();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<SubmitOrderResp> submit(OrderReq req) {

        Long memberId = req.getMemberId();

        Goods goods = goodsMapper.selectById(req.getGoodsId());

        req.setDiscountMoney(0);
        req.setCouponRatio(goods.getCouponRatio());

        Integer memberCouponId = req.getMemberCouponId();
        if (memberCouponId != null) {
            MemberCoupon memberCoupon = memberCouponMapper.selectById(memberCouponId);
            if (memberCoupon == null) {
                return Result.fail("找不到代金券");
            }

            if (!memberId.equals(memberCoupon.getMemberId())) {
                return Result.fail("代金券不属于你");
            }

            if (memberCoupon.getStatus() != 0) {
                return Result.fail("代金券不能使用");
            }

            String endTime = memberCoupon.getEndTime();
            if (endTime != null) {
                LocalDateTime dateTime = DateUtil.toDateTime(endTime);
                if (dateTime.isBefore(LocalDateTime.now())) {
                    return Result.fail("代金券已过期");
                }
            }

            //最大可优惠
            req.setDiscountMoney(memberCoupon.getMoney());
        }

        Result result = validSubmit(req);
        if (result.isFail()) {
            return result;
        }


        // 生成订单号
        String orderId = IdUtil.generatedCommonId(IdTagEnum.order).toString();
        log.info("generated_order_id=" + orderId);

        Order order = new Order();
        order.setOrderId(orderId);
        order.setMemberId(memberId);
        order.setName(req.getMobile());
        order.setMobile(req.getMobile());
        order.setShopId(goods.getShopId());
        order.setShopName(goods.getShopName());
        order.setType(goods.getType());
        order.setMemberCouponId(req.getMemberCouponId());
        order.setReceiveMobile(req.getReceiveMobile());
        order.setReceiveName(req.getReceiveName());
        order.setReceiveAddress(req.getReceiveAddress());
        order.setReceivePathId(req.getReceivePathId());
        order.setReceivePathName(req.getReceivePathName());
        order.setFreightMoney(req.getFreightMoney());
        order.setGoodsMoney(req.getGoodsMoney());
        order.setTotalMoney(req.getTotalMoney());
        order.setDiscountMoney(req.getDiscountMoney());
        order.setCouponRatio(req.getCouponRatio());
        order.setRealMoney(req.getRealMoney());
        order.setRemark(req.getRemark());
        order.setStatus(OrderStatusEnum.INIT.getValue());
        orderMapper.insert(order);

        OrderGoods orderGoods = new OrderGoods();
        orderGoods.setOrderId(orderId);
        orderGoods.setGoodsId(req.getGoodsId());
        orderGoods.setMemberId(memberId);
        orderGoods.setShopId(goods.getShopId());
        orderGoods.setGoodsId(goods.getId());
        orderGoods.setGoodsImg(goods.getImg());
        orderGoods.setGoodsTitle(goods.getTitle());
        orderGoods.setSpec(req.getSpec());
        orderGoods.setCount(req.getCount());
        orderGoods.setUnitPrice(req.getUnitPrice());
        orderGoods.setTotalPrice(req.getGoodsMoney());
        orderGoodsMapper.insert(orderGoods);

        OrderActionLog actionLog = new OrderActionLog();
        actionLog.setOrderId(orderId);
        actionLog.setFroms("客户端");
        actionLog.setAction("提交订单");
        actionLog.setMemberId(memberId);
        actionLog.setUsername(req.getMobile());
        orderActionLogMapper.insert(actionLog);

        //标记代金券已使用
        MemberCoupon update = new MemberCoupon();
        update.setId(memberCouponId);
        update.setStatus(1);
        update.setUseOrderId(orderId);
        update.setUseTime(DateUtil.getNowDateTime());
        memberCouponMapper.updateById(update);

        //返回 订单号 和 应付订单金额
        SubmitOrderResp resp = new SubmitOrderResp();
        resp.setOrderId(orderId);
        resp.setMoney(order.getRealMoney());
        return Result.ok(resp);
    }

    private Result validSubmit(OrderReq req) {

        Integer total = 0;

        Integer goodsMoney = req.getCount() * req.getUnitPrice();
        if (!goodsMoney.equals(req.getGoodsMoney())) {
            return Result.fail("商品金额不对");
        }

        total += goodsMoney;

        if (req.getFreightMoney() != null) {
            total += req.getFreightMoney();
        }

        if (req.getMemberCouponId() != null) {

            Integer discountMax = MathUtil.discount(goodsMoney, req.getCouponRatio());
            if (req.getDiscountMoney() > discountMax) {
                req.setDiscountMoney(discountMax);
            }

            total -= req.getDiscountMoney();

        }

        // 校验订单总金额
        if (!req.getRealMoney().equals(total)) {
            return Result.fail(FailMessage.ORDER_PRICE_FAIL);
        }

        return Result.ok();
    }

    @Override
    public Result<Order> detail(String orderId) {

        Order order = orderMapper.selectByOrderId(orderId);
        if (order == null) {
            return Result.ok();
        }

        OrderGoods goods = orderGoodsMapper.selectByOrderId(orderId);
        order.setGoodsImg(goods.getGoodsImg());
        order.setGoodsTitle(goods.getGoodsTitle());
        order.setSpec(goods.getSpec());
        order.setCount(order.getCount());
        order.setUnitPrice(order.getUnitPrice());

        return Result.ok(order);
    }

    @Override
    public Result<Integer> queryMoney(String orderId) {
        Order order = orderMapper.selectByOrderId(orderId);
        if (order == null) {
            return Result.ok();
        }

        return Result.ok(order.getTotalMoney());
    }

    @Override
    public Result cancel(CancelOrderReq req) {

        String orderId = req.getOrderId();

        Order order = orderMapper.selectByOrderId(orderId);
        if (order == null) {
            return Result.ok();
        }
        //检查订单状态
        if (order.getStatus() != OrderStatusEnum.INIT.getValue()) {
            log.info("order_not_refund,orderId=" + orderId);
            return Result.fail("订单不能取消");
        }

        Order update = new Order();
        update.setId(order.getId());
        update.setStatus(OrderStatusEnum.CANCEL.getValue());
        update.setRemark(req.getReason());
        update.setCancelTime(DateUtil.getNowDateTime());
        orderMapper.updateById(update);

        OrderActionLog actionLog = new OrderActionLog();
        actionLog.setOrderId(orderId.toString());
        actionLog.setFroms(req.getFroms());
        actionLog.setAction("取消");
        actionLog.setUserId(req.getUserId());
        actionLog.setMemberId(req.getMemberId());
        actionLog.setUsername(req.getUsername());
        orderActionLogMapper.insert(actionLog);

        return Result.ok();
    }

    @Override
    public Result queryStatus(String orderId) {
        Order order = orderMapper.selectByOrderId(orderId);
        return Result.ok(order.getStatus());
    }

    @Override
    public Result send(String orderId, MerchantJwt merchantJwt) {

        Order order = orderMapper.selectByOrderId(orderId);
        if (order == null) {
            return Result.ok();
        }
        //检查订单状态
        if (order.getStatus() != OrderStatusEnum.HAS_PAID.getValue()) {
            log.info("order_status_wrong,orderId=" + orderId);
            return Result.fail("订单不能配送");
        }

        Order update = new Order();
        update.setId(order.getId());
        update.setStatus(OrderStatusEnum.HAS_SEND.getValue());
        orderMapper.updateById(update);

        OrderActionLog actionLog = new OrderActionLog();
        actionLog.setOrderId(orderId);
        actionLog.setFroms("后端");
        actionLog.setAction("已配送");
        actionLog.setMemberId(merchantJwt.getMemberId());
        actionLog.setUsername(merchantJwt.getMobile());
        orderActionLogMapper.insert(actionLog);

        return Result.ok();
    }

    @Override
    public Result confirm(String orderId) {

        Order order = orderMapper.selectByOrderId(orderId);
        if (order == null) {
            return Result.ok();
        }

//        这边商家结算规则，按原型看，加入一笔订单收入是1000
//
//        店铺收入=1000*（1-1%-0.1%-0.5%）结算人bizno为店铺开户时候的bizno
//        平台服务费=1000*1% 这个待确定，看何老师这边打算怎么开户  10
//        平台手续费=1000*0.1% 记录结算人bizNo为0  1
//        第三方服务费=1000*0.5% 记录结算人bizNo为0  5
//        要记录对应的订单号，我回传给你的主汇付订单号和支付订单号，下单用户信息，具体看你们报表要怎么生成


        //金额分
        Integer payMoney = order.getRealMoney();

        if (order.getRefundMoney() != null) {
            payMoney -= order.getRefundMoney();
        }

        BigDecimal merchantMoney = new BigDecimal(payMoney).multiply(new BigDecimal(16)).divide(THOUSAND, RoundingMode.HALF_DOWN);
        BigDecimal sysSerMoney = new BigDecimal(payMoney).multiply(new BigDecimal(10)).divide(THOUSAND, RoundingMode.HALF_DOWN);
        BigDecimal sysSxMoney = new BigDecimal(payMoney).multiply(new BigDecimal(1)).divide(THOUSAND, RoundingMode.HALF_DOWN);
        BigDecimal thirdMoney = new BigDecimal(payMoney).multiply(new BigDecimal(5)).divide(THOUSAND, RoundingMode.HALF_DOWN);


        return null;
    }

    public static void main(String[] args) {

        BigDecimal bigDecimal = new BigDecimal(1011);
        BigDecimal divide = bigDecimal.divide(new BigDecimal(78), RoundingMode.HALF_DOWN);
        System.out.println(divide);

        BigDecimal divide2 = bigDecimal.divide(new BigDecimal(78), RoundingMode.HALF_DOWN);
        System.out.println(divide2);

    }
}